﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using System.Collections.ObjectModel;
using System.Xml;
using System.Xml.XPath;


using log4net;
using CommonLib;


namespace RedfinCrawlPro
{

    public class GeoCoordinate
    {
        private static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
        public GeoCoordinate() { }
        public GeoCoordinate(double lat, double Long)
        {
            this.Lat = lat;
            this.Long = Long;
        }
        public double Lat   { get; set; }
        public double Long { get; set; } 
    }


    public class RedfinConfig: FetcherConfigBaseRec                                                                                                 
    {
        private static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
        private const string nameAttrString = "name";
        private const string typeAttrStr = "type";
        private const string walkScoreAttrString = "walkScore";
        private const string crimeScoreAttrString = "crimeScore";
        private const string zillowQueryAttrString = "zillowQuery";        
        private const string activeAttrString = "active";
        private const string GeoPointString = "./GeoPolygon/geoPoint";
        private const string latString = "lat";
        private const string longString = "long";
        private const string cityNameString = "./CityName";

        private const string processorString = "./Processors/processor";

        public bool WalkScore { get; private set; }
        public bool CrimeScore { get; private set; }
        public bool zillowRegionStats { get; private set; }
        public string cityName { get; private set; }

        private   List<GeoCoordinate>        _polygonGeopoints { get;  set; }


        public ReadOnlyCollection<GeoCoordinate> PolygonGeopoints
        {
            get
            {
                ReadOnlyCollection<GeoCoordinate> readOnlyCollection = new ReadOnlyCollection<GeoCoordinate>(_polygonGeopoints);
                return readOnlyCollection;
            }

        }

        public RedfinConfig()
        {
            _polygonGeopoints = new List<GeoCoordinate>();
            WalkScore  = false;
            CrimeScore = false;
            zillowRegionStats = false;
        }

        public bool LoadConfiguration(XmlNode fetcherNode)
        {
            XmlAttribute xmlAttr = null;

            Console.Write("Reading Fetcher Record  ");

            // read fetcher Name Attribute 
            xmlAttr = fetcherNode.Attributes[nameAttrString];
            if (xmlAttr == null)
            {
                log.DebugFormat("AttributeMissing : " + nameAttrString +" :  For fetcher Record ");
                return false;
            }
            _FetcherName = xmlAttr.Value;

            log.DebugFormat("Name: " + FetcherName); 

            //  Walk Score Attribute
            xmlAttr = fetcherNode.Attributes[walkScoreAttrString];
            if (xmlAttr != null)
            {
                WalkScore = System.Convert.ToBoolean(xmlAttr.Value);
            }

            // CrimeScore Attribute 
            xmlAttr = fetcherNode.Attributes[crimeScoreAttrString];
            if (xmlAttr != null)
            {
                CrimeScore = System.Convert.ToBoolean(xmlAttr.Value);
            }

            xmlAttr = fetcherNode.Attributes[zillowQueryAttrString];
            if (xmlAttr != null)
            {
                zillowRegionStats = System.Convert.ToBoolean(xmlAttr.Value);
            }

            _isActive = true;
            xmlAttr = fetcherNode.Attributes[activeAttrString];
            if (xmlAttr != null)
            {
                _isActive = System.Convert.ToBoolean(xmlAttr.Value);
            }


            // read fetcher Type  Attribute 
            xmlAttr = fetcherNode.Attributes[typeAttrStr];
            if (xmlAttr == null)
            {
                log.FatalFormat("AttributeMissing : " + typeAttrStr + " :  For fetcher Record ");
                return false;
            }

            _FetcherType = xmlAttr.Value;

            

            // Get The City Name , Btw it is optional 

            XmlNode cityNameNode = fetcherNode.SelectSingleNode(cityNameString);
            if (cityNameNode != null)
            {
                cityName = cityNameNode.InnerText;
                log.DebugFormat(" City Name Present :{0}", cityName);
            }

            // get PolyGon Co ordinates
            XmlNodeList geoPointNodes = fetcherNode.SelectNodes(GeoPointString);
            if( geoPointNodes == null )
            {
                log.DebugFormat("Geo Point List Missing ( Geo Polygon)  :  For fetcher Record ");
                return false;
            }

            log.DebugFormat("Reading GeoPoint/Polygon data ");
            foreach (XmlNode geoPoint in geoPointNodes)
            {
                GeoCoordinate gp = new GeoCoordinate();
                 xmlAttr = geoPoint.Attributes[latString];
                 if (xmlAttr == null)
                 {
                     return false;
                 }
                 gp.Lat = System.Convert.ToDouble(xmlAttr.Value);

                 xmlAttr = geoPoint.Attributes[longString];
                 if (xmlAttr == null)
                 {
                     return false;
                 }
                 gp.Long = System.Convert.ToDouble(xmlAttr.Value);

                // Add to geopoint lust 
                 _polygonGeopoints.Add(gp);
            }

            log.DebugFormat("Finsihed Reading Fetcher Record for " + FetcherName);
            return true;
        }

    }
}
